package site.beanyon.now.shiro;

import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import site.beanyon.now.model.dto.UserDTO;
import site.beanyon.now.model.po.UserPO;
import site.beanyon.now.service.UserService;
import site.beanyon.now.util.PasswordUtils;

/**
 * 自定义Shiro用户领域定义，实现认证、授权相关的业务
 */
public class UserRealm extends AuthorizingRealm {
    @Lazy
    @Autowired
    private UserService userService;

    /**
     * 执行认证逻辑
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        // 获取用户的登录帐号和密码
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;

        // 用户登录账号和密码
        String tel = token.getUsername();
        String password = String.valueOf(token.getPassword());

        // 根据登录帐号，从数据库中读取用户信息
        UserPO userPO = this.userService.getUser(tel);

        // 判断账号是否有效（用户是否存在）
        if (userPO == null) {
            // Shiro底层会抛出UnknownAccountException
            return null;
        }

        UserDTO userDTO = new UserDTO(userPO);

        // 为用户密码加盐
        String newPassword = PasswordUtils.addSaltToPassword(password, userPO.getSalt());

        // 将加盐后的密码设置回去
        token.setPassword(newPassword.toCharArray());

        // 第二个参数传入从数据库中获取的密码，Shiro会自动和用户输入的密码进行比对
        return new SimpleAuthenticationInfo(userDTO, userPO.getPassword(), "");
    }

    /**
     * 执行授权逻辑
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//        UserPO user = (UserPO) principalCollection.getPrimaryPrincipal();
//
//        //根据用户信息获取用户权限
//        Set<String> permissionSet = userService.getUserPermissions(user.getId());
//
//        //封装用户权限
//        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//        info.setStringPermissions(permissionSet);
//        return info;
        return null;
    }
}
